import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class OuterController extends JPanel{

    private int num;    //外呼组内电梯数量
    private static OuterController instance = new OuterController();    //外呼控制器的单例
    protected static JButton[] directionButton;     //外呼按钮组
    protected HElevator[] elevator; //外呼控制器控制的电梯组

    private OuterController(){
        num = 2;    //电梯组内有两个电梯

        directionButton = new JButton[40];
        for(int i=0; i<40; i++) {
            if(i == 1 || i == 38)
                continue;           //底层和顶层分别不设置向下和向上按钮

            //i为偶数表示向上按钮
            if(i % 2 == 0) {
                directionButton[i] = new JButton("上");
                directionButton[i].setBackground(Color.WHITE);
                directionButton[i].setBounds(180, 650 - 15 * i, 50, 20);

                JButton temp = directionButton[i];
                int tempFloor = i/2 + 1;    //表示按钮所在楼层

                //给向上按钮添加监听器
                directionButton[i].addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        temp.setBackground(Color.YELLOW);                    //若按下按钮，颜色改变
                        int id = chooseElevator(tempFloor, HElevator.UP);   //选择要调度的电梯id
                        HElevator h = elevator[id];

                        h.setRandomCmd(tempFloor, 2);
                        if (h.getDirection() == HElevator.PAUSED) {
                            h.setLastCmd(tempFloor);    //如果电梯是空闲状态，把楼层按键的值设为最终目标楼层
                        }

                        if (h.getDirection() == HElevator.UP) {
                            h.setLastCmd(h.getMaxCmd());
                        }

                        if (h.getDirection() == HElevator.DOWN) {
                            h.setLastCmd(h.getMinCmd());
                        }
                    }
                });
            }
            else {
                directionButton[i] = new JButton("下");
                directionButton[i].setBackground(Color.WHITE);
                directionButton[i].setBounds(230, 650-15 * (i-1), 50, 20);

                JButton temp = directionButton[i];
                int tempFloor = i/2 + 1;

                directionButton[i].addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        temp.setBackground(Color.YELLOW);
                        int id = chooseElevator(tempFloor, HElevator.DOWN);   //选择要调度的电梯id
                        HElevator h = elevator[id];

                        h.setRandomCmd(tempFloor, 2);
                        if (h.getDirection() == HElevator.PAUSED) {
                            h.setLastCmd(tempFloor);    //如果电梯是空闲状态，把楼层按键的值设为最终目标楼层
                        }

                        if (h.getDirection() == HElevator.UP) {
                            h.setLastCmd(h.getMaxCmd());
                        }

                        if (h.getDirection() == HElevator.DOWN) {
                            h.setLastCmd(h.getMinCmd());
                        }
                    }
                });
            }
        }

        elevator = new HElevator[num];
        elevator[0] = new HElevator(0);
        elevator[1] = new HElevator(1);
    }

    //外呼选择调度的电梯id
    private int chooseElevator(int outterCmdFloor, int direction) {

        if(elevator[0].getState() == HElevator.REPAIR && elevator[1].getState() == HElevator.RUN)
            return 1;
        if(elevator[1].getState() == HElevator.REPAIR && elevator[0].getState() == HElevator.RUN)
            return 0;

        int gapFloor1 = getGap(elevator[0], outterCmdFloor, direction);      //用来记录电梯当前所在楼层运行到外呼目标楼层所要经过的楼层数
        int gapFloor2 = getGap(elevator[1], outterCmdFloor, direction);

        if(gapFloor2 < gapFloor1) {   //就近调度
            return 1;
        }
        else {
            return 0;
        }
    }

    //计算电梯当前所在楼层运行到外呼目标楼层所要经过的楼层数
    private int getGap(HElevator e, int outterCmdFloor, int direction) {

        int gapFloor = 0;
        int currentFloor = e.getCurrentFloor();

        if(e.getDirection() == HElevator.PAUSED)
            gapFloor = Math.abs(currentFloor - outterCmdFloor);

        if(direction == HElevator.UP){
            if(e.getDirection() == HElevator.UP && currentFloor < outterCmdFloor)
                gapFloor = outterCmdFloor - currentFloor;

            if(e.getDirection() == HElevator.UP && currentFloor > outterCmdFloor)
                gapFloor = 2 * e.getMaxCmd() - 2*e.getMinCmd() + outterCmdFloor - currentFloor;

            if(e.getDirection() == HElevator.DOWN )
                gapFloor = currentFloor + outterCmdFloor - 2 * e.getMinCmd();

        }
        else if(direction == HElevator.DOWN){
            if(e.getDirection() == HElevator.UP)
                gapFloor = 2 * e.getMaxCmd() - currentFloor - outterCmdFloor;

            if(e.getDirection() == HElevator.DOWN && currentFloor < outterCmdFloor)
                gapFloor = 2 * e.getMaxCmd() - 2 * e.getMinCmd() + currentFloor - outterCmdFloor;

            if(e.getDirection() == HElevator.DOWN && currentFloor > outterCmdFloor)
                gapFloor = currentFloor - outterCmdFloor;
        }

        return gapFloor;
    }

    public  static OuterController getInstance(){
        return instance;
    }



}
